package org.wangp.gateway.oa.config;

import java.util.List;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.wangp.gateway.oa.service.UserDetailService;

/**
 * @author wangpeng (๑•ᴗ•๑)
 * @since 2021/10/6 2:37
 */
@Configuration
@EnableAuthorizationServer
public class Oauth2ServerConfig extends AuthorizationServerConfigurerAdapter {

	private final PasswordEncoder passwordEncoder;
	private final AuthenticationManager authenticationManager;
	private final TokenEnhancer tokenEnhancer;
	private final JwtAccessTokenConverter jwtAccessTokenConverter;
	private final UserDetailService userDetailService;

	public Oauth2ServerConfig(final PasswordEncoder passwordEncoder, final AuthenticationManager authenticationManager,
			final TokenEnhancer tokenEnhancer,
			@Qualifier("accessTokenConverter") final JwtAccessTokenConverter jwtAccessTokenConverter,
			final UserDetailService userDetailService) {
		this.passwordEncoder = passwordEncoder;
		this.authenticationManager = authenticationManager;
		this.tokenEnhancer = tokenEnhancer;
		this.jwtAccessTokenConverter = jwtAccessTokenConverter;
		this.userDetailService = userDetailService;
	}

	/**
	 * 配置令牌的安全约束
	 *
	 * @param security
	 */
	@Override
	public void configure(final AuthorizationServerSecurityConfigurer security) {
		security.allowFormAuthenticationForClients();
	}

	/**
	 * 配置客户端详情服务
	 *
	 * @param clients
	 * @throws Exception
	 */
	@Override
	public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
		clients.inMemory().withClient("client-app").secret(this.passwordEncoder.encode("123456")).scopes("all")
				.authorities("password", "refresh_token").accessTokenValiditySeconds(3600)
				.accessTokenValiditySeconds(86400);
	}

	/**
	 * 配置令牌服务
	 *
	 * @param endpoints
	 */
	@Override
	public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
		final var tokenEnhancerChain = new TokenEnhancerChain();
		tokenEnhancerChain.setTokenEnhancers(List.of(this.tokenEnhancer, this.jwtAccessTokenConverter));
		endpoints.authenticationManager(this.authenticationManager).userDetailsService(this.userDetailService)
				.accessTokenConverter(this.jwtAccessTokenConverter).tokenEnhancer(tokenEnhancerChain);
	}
}
